package com.javachamp.instanceoff;

public class InstanceOfRules {
	static class A {
	}

	static class B extends A implements C {
	}

	interface C {
	}

	static class D {
	}

	// ...
	public static void main(String[] args) {
		// first an instance of B is created
		// then reference of A is pointing new instance of B
		// java does not force developer to declare explicit casting
		// A a = (A) new B(); // also legal but not required
		A a = new B();

		// safe downcasting should be implemented like this:
		// checking the object referenced by reference 'a' is
		// instance of B.
		if (a instanceof B) {
			// if true than downcasting is safe
			// otherwise at runtime; java.lang.ClassCastException occurs
			B b = (B) a;
		}

		// any class reference can be controlled(instanceof) with any interface
		// casting must be explicitly declared
		if (a instanceof C) {
			C c = (C) a;
			// any interface reference can be controlled(instanceof) with any
			// class
			// casting must be explicitly declared
			if (c instanceof A) {
				A a2 = (A) c;
			}
		}

		// nonsense but no compiler warning or error
		if (new A() instanceof B) {
			B b = (B) new A(); // sad but true; runtime exception is certain
		}

		// valid always false
		if (null instanceof B) {
			System.out.println("Always false!");
		}

		// nonsense check with any unrelated classes; causes compiler error
		// if(a instanceof D) {
		// D d = (D) a;
		// }
	}
}
